#ifndef __RIO__H
#define __RIO__H
#include<unistd.h>
#include<string.h>
#include<errno.h>
#define RIO_BUFSIZE 8192

typedef struct
{   
    int rio_fd;
    int rio_cnt;
    char* rio_bufptr;
    char* rio_buf[RIO_BUFSIZE];
} rio_t;


// no buffer
ssize_t rio_readn(int fd, void* usrbuf, size_t n);
ssize_t rio_writen(int fd, void* usrbuf, size_t n);

// hava buffer
void rio_readinitb(rio_t* rp, int fd);
ssize_t rio_readlineb(rio_t* rp, void* usrbuf, size_t maxlen);
ssize_t rio_readnb(rio_t* rp, void* usrbuf, size_t n);

static ssize_t rio_read(rio_t *rp, char *usrbuf, size_t n) {
  while (rp->rio_cnt <= 0) {
    rp->rio_cnt = read(rp->rio_fd, rp->rio_buf, sizeof(rp->rio_buf));
    if (rp->rio_cnt < 0) {
      if (errno != EINTR) {
        return -1;
      }
    } else if (rp->rio_cnt == 0) {
      return 0;
    } else {
      rp->rio_bufptr = (char*)rp->rio_buf;
    }
  }
  int cnt = n;
  if (rp->rio_cnt < n) {
    cnt = rp->rio_cnt;
  }
  memcpy(usrbuf, rp->rio_bufptr, cnt);
  rp->rio_bufptr += cnt;
  rp->rio_cnt -= cnt;
  return cnt;
}
#endif